﻿namespace BM.Tools.WebControls.MForm
{
    using System.Diagnostics.CodeAnalysis;
    using System.Globalization;
    using System.IO;
    using System.Text;
    using System.Xml;
    using System.Xml.Serialization;
    using System.Xml.XPath;

    /// <summary>
    /// This class is used to easily convert objects to xml.
    /// </summary>
    public static class ObjectToXmlConverter
    {
        /// <summary>
        /// Creates an <see cref="XPathDocument" /> from the object.
        /// </summary>
        /// <param name="value">
        /// The Object.
        /// </param>
        /// <returns>
        /// the xpath document.
        /// </returns>
        [SuppressMessage("Microsoft.Design", "CA1059:MembersShouldNotExposeCertainConcreteTypes", MessageId = "System.Xml.XPath.XPathDocument", Justification = "Specific functionality provided by the concrete type is required")]        
        public static XPathDocument ToXPathDocument(this object value)
        {
            StringBuilder builder = GetStringBuilder(value);
            using (var reader = new StringReader(builder.ToString()))
            {
                return new XPathDocument(reader);
            }
        }

        /// <summary>
        /// Creates an <see cref="XmlDocument" /> from the object.
        /// </summary>
        /// <param name="value">
        /// The Object.
        /// </param>
        /// <returns>
        /// the xml document.
        /// </returns>
        [SuppressMessage("Microsoft.Design", "CA1059:MembersShouldNotExposeCertainConcreteTypes", MessageId = "System.Xml.XmlNode", Justification = "Specific functionality provided by the concrete type is required")]
        public static XmlDocument ToXmlDocument(this object value)
        {
            StringBuilder builder = GetStringBuilder(value);
            using (var reader = new StringReader(builder.ToString()))
            {
                var document = new XmlDocument();
                document.Load(reader);
                return document;
            }
        }

        private static StringBuilder GetStringBuilder(object value)
        {
            var builder = new StringBuilder();
            var serializer = new XmlSerializer(value.GetType());
            using (var writer = new StringWriter(builder, CultureInfo.InvariantCulture))
            {
                serializer.Serialize(writer, value);
            }

            return builder;
        }
    }
}
